Skip to content

Conversation

@JelleKerkstra
Copy link

This PR resolves the DynamicProxyException Duplicate element: Castle.DynamicProxy.Generators.MetaMethod when generating a proxy that implements the following interfaces due to the nested classes.
In the current implementation, only the namespace, type name and method name are considered. In this PR, the declaring type names are also used when generating explicit interface implementations due to matching method names.

public static class OuterWrapper
{
	public static class InnerWrapperA
	{
		public interface ISharedName
		{
			void M();
		}
	}

	public static class InnerWrapperB
	{
		public interface ISharedName
		{
			void M();
		}
	}

	public static class InnerWrapperC
	{
		public interface ISharedName
		{
			void M();
		}
	}
}

nameBuilder.Append('.');
}
AppendTypeName(nameBuilder, sourceType);
AppendTypeName(nameBuilder, sourceType, true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not simply call AppendFullTypeName directly instead of going through AppendTypeName using that new parameter?

else if (ns != null)
{
this.name = string.Concat(ns, ".", sourceType.Name, ".", name);
this.name = string.Concat(ns, ".", GetFullTypeName(sourceType), ".", name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remember correctly, the pre-existing code in SwitchToExplicitImplementationName was written the way it is based on the assumption that string.Concat would be faster than instantiating a StringBuilder. The first if clause is therefore the slow path, while the other two are supposedly fast paths.

Your code change introduces StringBuilders in the fast paths, too, so from a performance perspective, they're now all the same and it seems likely that the distinction between three cases no longer needs to be made.

So if we go with your change, that whole method could perhaps be simplified to a single case where a StringBuilder is always instantiated at the start and there are various ifs for the presence/absence of a namespace, for the presence/absence of generic type arguments, etc.

If we go with the existing code's structure, you'd have to find a way of not relying on StringBuilder on the fast paths.

I think I'd favor simplifying the code by rewriting the if conditions to something more obvious, even if it means we no longer have the string.Concat fast paths.

@stakx
Copy link
Member

stakx commented Nov 23, 2025

@JelleKerkstra, apologies for the very long delay. I realise it has been more than a year since you submitted this PR. If you're no longer interested in this, that's OK, too. Let me know whether or not you'd like to proceed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants